package com.example.demo.controller;


import com.example.demo.common.AjaxResult;
import com.example.demo.common.ApplicationVariable;
import com.example.demo.common.StringTools;
import com.example.demo.common.UserSessionTools;
import com.example.demo.entity.ArticleInfo;
import com.example.demo.entity.UserInfo;
import com.example.demo.entity.vo.ArticleInfoVO;
import com.example.demo.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.List;


/**
 * 首先要做的就是加注解@Controller @ResponseBody 或者 @RestController
 * 注入 Service
 */
@RestController
@RequestMapping("/art") // article的缩写，最好全是小写，不要使用大写，因为在 linux 中发布时，会严格区分大小写
public class ArticleController {
    @Autowired
    private ArticleService articleService;

    @RequestMapping("/add") //统一返回数据格式
    /** 因为文章后续可能会增加字段，所以用对象传递，同时mapper.xml中也要进行添加字段
     *  由于还需要从会话中拿到 uid，所以传递 HttpServletRequest 对象，这个对象spring、框架帮我们注入了这个对象，直接写就好了
     */
    public AjaxResult add(ArticleInfo articleInfo, HttpServletRequest request) {
        // 1.非空校验
        if(articleInfo == null ||
                !StringUtils.hasLength(articleInfo.getTitle()) || //本身有值为true，我们是没有值才走下面步骤，所以加非空 ！
                !StringUtils.hasLength(articleInfo.getContent()))
            return AjaxResult.fail(-1,"标题或内容为空");
        // 2.组装数据，得到uid

        HttpSession session = request.getSession(true);
        // 因为已经走过拦截器了，所以不用加非空判断也行
        /**
         * 需要强转一下
         */
        UserInfo userInfo = (UserInfo)session.getAttribute(ApplicationVariable.SESSION_KEY_USERINFO);
        articleInfo.setUid(userInfo.getId());
        // 3.持久化，将结果返回给前端
        int result = articleService.add(articleInfo);
        return AjaxResult.success(result);
    }


    /**
     * 获取文章的详细信息，但是需要进行鉴权（判断文章的归属人 是否和 当前登录用户一致）
     * @param id
     * @param request
     * @return
     */
    // 修改的时候，先查询数据显示到页面中去
    @RequestMapping("getdetailbyid")
    public AjaxResult getDetailByIdAndUid(Integer id,HttpServletRequest request) {
        if(id == null || id <= 0) return AjaxResult.fail(-1,"参数有误");
        UserInfo userInfo = UserSessionTools.getLoginUser(request);
        ArticleInfo articleInfo = articleService.getDetailByIdAndUid(id, userInfo.getId());
        return AjaxResult.success(articleInfo);
    }


    // 修改文章
    @RequestMapping("/update") // 传递对象还是为了后续的方便修改
    public AjaxResult update(ArticleInfo articleInfo,HttpServletRequest request) {
        // 这里传递的 ArticleInfo 对象，框架会自动帮我们接收到前端传递过来的参数，并赋值给 ArticleInfo 对象，所以我们可以直接用就行
        // 1.非空校验
        // null 和 < 0 是表示不为空且有意义
        if(articleInfo == null || articleInfo.getId() <= 0 ||
            !StringUtils.hasLength(articleInfo.getTitle()) ||
            !StringUtils.hasLength(articleInfo.getContent()))
            return AjaxResult.fail(-1,"没有接收到前端传递过来的对象");
        // 获取登录用户的id，填充到 articleinfo 中去，用于修改文章时身份的验证
        articleInfo.setUid(UserSessionTools.getLoginUser(request).getId());
        articleInfo.setUpdatetime(LocalDateTime.now());
        int result = articleService.update(articleInfo);
        return AjaxResult.success(result);
    }


    // 查询某篇文章，没有身份校验（公共列表页中的某一篇文章的详情页）
    @RequestMapping("/getdetail")
    public AjaxResult getDetail(Integer id) {
        if(id == null || id <= 0)
            return AjaxResult.fail(-1,"id参数有误");
        ArticleInfoVO articleInfoVO = articleService.getDetail(id);
        return AjaxResult.success(articleInfoVO);
    }


    // 阅读量的增加

    /**
     * 注意还要拦截器中放行这个接口
     * @param id
     * @return
     */
    @RequestMapping("/addrcount")
    public AjaxResult addRCount(Integer id) {
        if(id == null || id <= 0 )
            return AjaxResult.fail(-1,"id参数有误");
        int result = articleService.addRCount(id);
        return AjaxResult.success(result);
    }

    // 根据 uid 来查询个人的文章，并显示到列表页
    @RequestMapping("/mylist")
    public AjaxResult getMyListByUid(HttpServletRequest request) {
        UserInfo userInfo = UserSessionTools.getLoginUser(request);
        // 已经走过拦截器了，所以不用判断为空的情况
        List<ArticleInfo> list = articleService.getMyListByUid(userInfo.getId());

        // 将文章正文截成摘要
        for (ArticleInfo item: list) {
            String content = StringTools.subLength(item.getContent(),150);
            /**
             * 待办事项：将 content 中的 markdown 关键字去掉
             */
            item.setContent(content);
        }
        return AjaxResult.success(list);
    }


    /**
     * 我的博客列表页中的删除文章操作
     * 前端传递id，我们用id接收，同时我们删除需要uid，所以通过 HttpServletRequest 对象来获取到用户id
     */
    //     这里我们需要判断归属人的问题 -->
    //     方案1：先查询文章，之后根据uid 和 当前登录用户 来判断是否一致 ， 需要两步操作-->
    //     方案2：直接传递过来一个uid，在 sql 中进行判断,选择方案2 更巧妙-->
//    @RequestMapping("/del")
//    public AjaxResult del(Integer id,HttpServletRequest request) {
//        if(id == null || id <= 0) return AjaxResult.fail(-1,"没有得到id参数");
//        UserInfo userInfo = UserSessionTools.getLoginUser(request);
//        int result = articleService.del(id, userInfo.getId());
//        return AjaxResult.success(result);
//    }


    /**
     * 用于测试保底的数据返回格式 是否正确
     * @param id
     * @param request
     * @return
     */
    @RequestMapping("/del")
    public int del(Integer id,HttpServletRequest request) {
        if(id == null || id <= 0) return 0;
        UserInfo userInfo = UserSessionTools.getLoginUser(request);
        int result = articleService.del(id, userInfo.getId());
        return result;
    }

    /**
     * 用于测试保底的数据返回格式 是否正确
     * @return
     */
    @RequestMapping("/test")
    public String test() {
        return "test";
    }


    /**
     * 分页查询文章
     * @param pageSize
     * @param pageIndex
     * @return
     */
    // 分页查询文章，因为没有作者名字所以ArticleInfo 就可以了
    @RequestMapping("/getlistbypage") // url不要有大小写，linux严格区分大小写,全小写就行，多个可以用下划线_
    public AjaxResult getListByPage( Integer pageIndex , Integer pageSize) {
        if(pageSize == null || pageSize <= 0) {
            // 这里不是提示参数有误，而是到首页，所以 pageSize 需要改一下
            // 默认一页两个文章
            pageSize = 2;
        }
        if(pageIndex == null || pageIndex <= 0) {
            // 这里不是提示参数有误，而是到首页，所以 pageSize 需要改一下
            // 默认一页两个文章
            pageIndex = 1;
        }

        int offset = pageSize * (pageIndex - 1);
        // 注意这里面获取到的是文章的全文，我们要进行摘要展示的
        List<ArticleInfo> list = articleService.getListByPage(pageSize,offset);
        // 并发的循环,先变成一个流，parallel()并发，forEach遍历
        list.stream().parallel().forEach(item -> {
            item.setContent(StringTools.subLength(item.getContent(),150));
        });
        return AjaxResult.success(list);
    }


    // 查询总页数
    @RequestMapping("/getcount")
    public AjaxResult getCount() {
        int result = articleService.getCount();
        return AjaxResult.success(result);
    }
}
